package com.core.common.gen;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.core.common.exception.BDException;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @program: kuntail
 * @description:
 * @author: honglei
 * @create: 2022-03-10 17:53
 */
public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,T> implements IBaseService<T>{



    @Override
    public IPage<T> selectPage(PageQuery<BaseQuery> pageQuery) {
        T t= null;
        try {
            t = (T) this.entityClass.newInstance();
            ;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return selectPage(t,pageQuery);
    }

    @Override
    public IPage<T> selectPage(T t,PageQuery<BaseQuery> pageQuery) {
        return selectPage(t,pageQuery,true);
    }

    @Override
    public IPage<T> selectPage(T t, PageQuery<BaseQuery> pageQuery, boolean copyBean) {

        IPage<T> page = new Page<>(pageQuery.getPageIndex(),pageQuery.getPageSize());
        if (Objects.isNull(t)){
            throw new BDException("分页查询参数错误！ T is null !");
        }
        if (Objects.isNull(pageQuery.getQueryBean())){
            pageQuery.setQueryBean(new BaseQuery());
        }

        formatBeanEmpty(t);
        convertFuzzySearch(pageQuery.queryBean);
        if (copyBean){
            BeanUtils.copyProperties(pageQuery.getQueryBean(),t);
        }

        QueryWrapper<T> queryWrapper= Wrappers.query(t);

        WrapperUtil.getInstance().initQueryToWrapper(queryWrapper,pageQuery.getQueryBean());

        IPage<T> iPage = this.baseMapper.selectPage(page,queryWrapper);
        return iPage;
    }




    @Override
    public List<T> selectList(BaseQuery queryBean)  {
        T t= null;
        try {
            t = (T) this.entityClass.newInstance();
            ;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return selectList(t,queryBean);
    }

    @Override
    public List<T> selectList(T t, BaseQuery queryBean) {
        return selectList(t,queryBean,true);
    }

    @Override
    public List<T> selectList(T t, BaseQuery queryBean,boolean copyBean) {

        formatBeanEmpty(t);
        convertFuzzySearch(queryBean);
        if (copyBean){
            BeanUtils.copyProperties(queryBean,t);
        }

        QueryWrapper<T> queryWrapper= Wrappers.query(t);
        WrapperUtil.getInstance().initQueryToWrapper(queryWrapper,queryBean);

        return this.baseMapper.selectList(queryWrapper);
    }

    @Transactional
    @Override
    public boolean batchSaveAfterDel(List<T> list, BaseQuery queryBean) {
        if (null !=queryBean && ! CollectionUtils.isEmpty(queryBean.getQueryConditions()) ){
            QueryWrapper<T> wrapper = Wrappers.query();
            WrapperUtil.getInstance().initQuery2Wrapper(wrapper,queryBean.getQueryConditions());
            remove(wrapper);
        }
        return saveBatch(list);
    }

    @Override
    public boolean removeByConditions(T t, BaseQuery queryBean) {
        BeanUtils.copyProperties(queryBean,t);
        QueryWrapper<T> wrapper= Wrappers.query(t);
        WrapperUtil.getInstance().initQuery2Wrapper(wrapper,queryBean.getQueryConditions());
        return remove(wrapper);
    }






    /***
     * ""-->null
     * @param object
     */
    public  void formatBeanEmpty(Object object){
        //获得字节码对象
        Class a = object.getClass();

        Field[] fields = a.getDeclaredFields();
        for (Field f : fields) {
            String type = f.getGenericType().toString();
            String name = f.getName();
            f.setAccessible(true);
            if (type.contains("String")) {
                try {
                    Object value = f.get(object);
                    if (value!=null && "".equals(value.toString())){
                        f.set(object, null);//填充值
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }






    private void convertFuzzySearch(BaseQuery queryBean ) {
        if (StringUtils.isEmpty(queryBean.getSearchText())){
            return;
        }
        if (CollectionUtils.isEmpty(initFuzzySearch())){
            return;
        }
        for (String column : initFuzzySearch()) {
            if (StringUtils.isEmpty(column)){
                return;
            }
            QueryCondition query=new QueryCondition();
            query.setColumnName(column);
            query.setOperator(EnumConditionOper.like);
            query.setValue(queryBean.getSearchText());
            queryBean.getFuzzySearchConditions().add(query);
        }

    }

    /***
     * 设置模糊搜索匹配字段
     * @param
     * @return
     */
    protected List<String> initFuzzySearch(){
        return new ArrayList<>();
    }


}
